package cn.luyou.admin.service.impl;

import cn.luyou.admin.dto.QuestionImportDTO;
import cn.luyou.admin.entity.Question;
import cn.luyou.admin.mapper.QuestionMapper;
import cn.luyou.admin.service.QuestionService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Override
    public IPage<Question> getQuestions(Integer pageNum, Integer pageSize, String keyword, String subject, String type, String difficulty) {
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.like(Question::getQuestionText, keyword);
        }
        if (StringUtils.hasText(subject)) {
            wrapper.eq(Question::getSubject, subject);
        }
        if (StringUtils.hasText(type)) {
            wrapper.eq(Question::getQuestionType, type);
        }
        if (StringUtils.hasText(difficulty)) {
            wrapper.eq(Question::getDifficulty, difficulty);
        }
        
        wrapper.orderByDesc(Question::getCreatedTime);
        return this.page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Transactional
    public void importQuestions(MultipartFile file, Long userId) {
        try {
            List<Question> questions = new ArrayList<>();
            EasyExcel.read(file.getInputStream(), QuestionImportDTO.class, new ReadListener<QuestionImportDTO>() {
                @Override
                public void invoke(QuestionImportDTO data, AnalysisContext context) {
                    Question question = new Question()
                            .setQuestionType(data.getQuestionType())
                            .setSubject(data.getSubject())
                            .setQuestionText(data.getQuestionText())
                            .setOptions(data.getOptions())
                            .setCorrectAnswer(data.getCorrectAnswer())
                            .setScore(data.getScore())
                            .setDifficulty(data.getDifficulty())
                            .setCreatedBy(userId);
                    questions.add(question);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // Save all questions
                    saveBatch(questions);
                }
            }).sheet().doRead();
        } catch (IOException e) {
            throw new IllegalArgumentException("导入失败：" + e.getMessage());
        }
    }

    @Override
    public byte[] exportQuestions(List<Long> ids) throws IOException {
        List<Question> questions;
        if (ids != null && !ids.isEmpty()) {
            questions = this.listByIds(ids);
        } else {
            questions = this.list();
        }

        List<QuestionImportDTO> dtos = questions.stream().map(q -> {
            QuestionImportDTO dto = new QuestionImportDTO();
            dto.setQuestionType(q.getQuestionType());
            dto.setSubject(q.getSubject());
            dto.setQuestionText(q.getQuestionText());
            dto.setOptions(q.getOptions());
            dto.setCorrectAnswer(q.getCorrectAnswer());
            dto.setScore(q.getScore());
            dto.setDifficulty(q.getDifficulty());
            return dto;
        }).collect(Collectors.toList());

        // Create a ByteArrayOutputStream to hold the Excel data
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        
        // Write data to Excel
        EasyExcel.write(outputStream, QuestionImportDTO.class)
                .sheet("题目列表")
                .doWrite(dtos);
        
        return outputStream.toByteArray();
    }

    @Override
    @Transactional
    public void removeDuplicates() {
        // Get all questions
        List<Question> questions = this.list();
        
        // Group questions by content and keep only one from each group
        questions.stream()
                .collect(Collectors.groupingBy(Question::getQuestionText))
                .values()
                .stream()
                .filter(group -> group.size() > 1)
                .forEach(group -> {
                    // Keep the first one, remove others
                    List<Long> idsToRemove = group.stream()
                            .skip(1)
                            .map(Question::getId)
                            .collect(Collectors.toList());
                    this.removeByIds(idsToRemove);
                });
    }

    @Override
    @Transactional
    public Question addQuestion(Question question) {
        // Check if question already exists
        if (this.count(new LambdaQueryWrapper<Question>()
                .eq(Question::getQuestionText, question.getQuestionText())) > 0) {
            throw new IllegalArgumentException("题目已存在");
        }
        
        this.save(question);
        return question;
    }

    @Override
    @Transactional
    public void updateQuestion(Question question) {
        Question existingQuestion = this.getById(question.getId());
        if (existingQuestion == null) {
            throw new IllegalArgumentException("题目不存在");
        }
        
        // Check if the updated question text conflicts with other questions
        if (!existingQuestion.getQuestionText().equals(question.getQuestionText())) {
            if (this.count(new LambdaQueryWrapper<Question>()
                    .eq(Question::getQuestionText, question.getQuestionText())) > 0) {
                throw new IllegalArgumentException("题目已存在");
            }
        }
        
        this.updateById(question);
    }

    @Override
    @Transactional
    public void deleteQuestion(Long id) {
        Question question = this.getById(id);
        if (question == null) {
            throw new IllegalArgumentException("题目不存在");
        }
        
        this.removeById(id);
    }
} 